<?php
namespace Cli\Controller;

use \Think\Controller;
use Think\Log;

/**
 * socket服务器
 * @modify trainyao 2016-02-03 创建
 */
class RemindController extends Controller {
    protected function _initialize() {
        if (!IS_CLI) {
            exit();
        }
    }

    public function remindStart() {
        $webSocketInstance = new \swoole_websocket_server(C('SOCKET_SERVER_REMIND_IP'), C('SOCKET_SERVER_REMIND_PORT'));

        $webSocketInstance->on('WorkerStart', function ($server, $worker_id) {
            if (!$worker_id >= $server->setting['worker_num'] && !$server->inited) {
                // 初始化redisInstance
                if (empty($server->redisInstance)) {
                    $server->redisInstance = new \Redis();
                    $connectResult = $server->redisInstance->connect(C('REDIS_SERVERIP'), C('REDIS_SERVERPORT'));
                    if ($connectResult) {
                        $server->redisConnect = true;
                        $server->redisInstance->auth(C('REDIS_AUTH_PASSWORD'));
                        $server->redisInstance->select(C('REDIS_ORDER_REMIND_DB'));
                    }
                }

                // 初始化task
                $server->tick(5000, function() use ($server) {
                    // 查redis数据
                    $data = array();
                    $dataValue = array();
                    if ($server->redisConnect) {
                        $data = $server->redisInstance->keys(C('REDIS_ORDER_REMIND_DB') . ':remind:*');
                        $appData = $server->redisInstance->keys(C('REDIS_ORDER_REMIND_DB') . ':appRemind:*');
                        if (!empty($data)) {
                            foreach ($data as $redisKey) {
                                $dataValue = $server->redisInstance->hGetAll($redisKey);
                                $RemindTime = $dataValue['remindTime'] - 300;

                                if ($RemindTime <= time()) {
                                    foreach ($server->hotels as $adminId => $clientIdsAndHotel) {
                                        if(!empty($clientIdsAndHotel)) {
                                            foreach ($clientIdsAndHotel as $clientId => $hotels) {
                                                if (in_array($dataValue['hotel'], $hotels)) {
                                                    // 发送消息
                                                    /*$dataArray = array(
                                                        'clientIdsAndHotel' => $clientIdsAndHotel,
                                                        'data' => $dataValue,
                                                    );*/
                                                    // web端发送消息
                                                    $server->push($clientId, json_encode(array(
                                                        'httpstatus' => 200,
                                                        'status' => 200,
                                                        'info' => '',
                                                        'data' => $data['data'],
                                                    )));
                                                    //$server->task($dataArray);
                                                }
                                            }
                                            unset($hotels);
                                        }
                                    }
                                    unset($clientIdsAndHotel);

                                    if (!empty($server->hotels)) {
                                        // 使消息失效
                                        $server->redisInstance->EXPIREAT($redisKey, 0);
                                    }
                                }
                            }
                            unset($redisKey);
                        }

                        if (!empty($appData)) {
                            foreach ($appData as $redisKey) {
                                $dataValue = $server->redisInstance->hGetAll($redisKey);
                                $RemindTime = $dataValue['remindTime'] - 300;
                                if ($RemindTime <= time()) {
                                    // app推送
                                    $server->task(array('data' => $dataValue));
                                    // 使消息失效
                                    $server->redisInstance->EXPIREAT($redisKey, 0);
                                }
                            }
                            unset($redisKey);
                        }
                    }
                });
                $server->hotels = array();
                $server->connectorHotel = array();
                $server->inited = true;
            }
        });

        $webSocketInstance->on('message', function ($server, $frame) {
            $clientId = $frame->fd;
            $msg = $frame->data;

            $msg = json_decode($msg, true);
            $HotelRoomAuthorityModel = D('HotelRoomAuthority');
            $adminHotelModel = D('AdminHotel');
            // 获取用户管理客栈id 并且客栈开启状态
            $adminHotelInfo = $adminHotelModel->getInfoByUserLeftHotelEntity($msg['adminId']);
            $userHotelIds = array_column($adminHotelInfo, 'hotelentity_id');
            // 保存客栈用户关系
            if (empty($server->hotels)) {
                $server->hotels[$msg['adminId']] = array(
                    $frame->fd =>  $userHotelIds,
                );
            } else {
                if (isset($server->hotels[$msg['adminId']])) {
                    $server->hotels[$msg['adminId']][$frame->fd] = $userHotelIds;
                } else {
                    $server->hotels[$msg['adminId']] = array(
                        $frame->fd =>  $userHotelIds,
                    );
                }
            }
            $server->connectorHotel[$frame->fd] = $msg['adminId'];
            $server->push($frame->fd, json_encode(array(
                    'httpstatus' => 200,
                    'status' => 200,
                    'info' => '',
            )));
        });

        //监听WebSocket连接关闭事件
        $webSocketInstance->on('close', function ($server, $clientId, $from_id) {

            $adminId = $server->connectorHotel[$clientId];
            unset($server->hotels[$adminId][$clientId]);
            unset($server->connectorHotel[$clientId]);
        });

        $webSocketInstance->on('task', function ($server, $task_id, $from_id, $data) {
            // 更新推送数据 （标为已推送）
            $hotelAlarmClockModel = D('HotelAlarmClock');
            $saveResult = $hotelAlarmClockModel->setRemind($data['data']['alarmClockId']);

            /*foreach ($data['clientIdsAndHotel'] as $clientId => $hotels) {
                $server->push($clientId, json_encode(array(
                    'httpstatus' => 200,
                    'status' => 200,
                    'info' => '',
                    'data' => $data['data'],
                )));
            }*/

            // 是否开启美住app功能
            $hotelLogic = A('Common/Hotel', 'Logic');
            $resultEnable = $hotelLogic->checkHotelAppEnable($data['data']['hotel']);
            if ($resultEnable) {
                // 推送目标 客栈下所有用户
                $adminHotelInfo = D('AdminHotel')->getUserInfo($data['data']['hotel']);
                $alias = array_column($adminHotelInfo, 'adminlogin_id');

                // 调用推送接口 app端
                $jpushConfig = C('JPUSH_CONFIG');
                vendor('jpush.autoload');
                $jpushUtil = new \JPush\Client($jpushConfig['appID'], $jpushConfig['appSecret'], $jpushConfig['logPath']);
                $push = $jpushUtil->push();
                $errorMsg = '';
                try {
                    $push->setPlatform(array('ios', 'android'))
                        ->setNotificationAlert($data['data']['alertNews']);

                    // 查看是否在调试模式,如果是,消息只发送到测试tag的用户
                    if ($jpushConfig['debug']) {
                        $push->addAlias($alias);
                        $push->addTag(array('test'));
                        $push->options(array(
                            'apns_production' => false,
                        ));
                    } else {
                        $push->addAlias($alias);
                        $push->options(array(
                            'apns_production' => true,
                        ));
                    }

                    $result = $push->send();
                } catch (\JPush\Exceptions\APIConnectionException $e) {
                    $errorMsg = $e->getMessage();
                    \Think\Log::write($errorMsg . "\r\n", \Think\Log::ERR, '', $jpushConfig['logPath']);
                }
            }
        });

        $webSocketInstance->on('finish', function ($server) {
        });

        $webSocketInstance->set(array(
            'task_worker_num' => 4,
            'worker_num'      => 1,
            'max_request'     => 5000,
            'daemonize' => 1,
        ));
        $webSocketInstance->start();
    }
    public function stop() {
    }
}